home *** CD-ROM | disk | FTP | other *** search
/ 130 MIDI Tool Box / 130 MIDI Tool Box.iso / drum / drumfile.c < prev    next >
C/C++ Source or Header  |  1992-02-19  |  8KB  |  256 lines

  1. /*------------------------------------------
  2.    DRUMFILE.C -- File I/O Routines for DRUM
  3.                  (c) Charles Petzold, 1992
  4.   ------------------------------------------*/
  5.  
  6. #include <windows.h>
  7. extern "C" {
  8. #include <mmsystem.h>
  9. #include <commdlg.h>
  10. }
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <time.h>
  14. #include "drumdll.h"
  15. #include "drumfile.h"
  16.  
  17. OPENFILENAME ofn = { sizeof (OPENFILENAME) } ;
  18.  
  19. char * szFilter[] = { "Drum Files (*.DRM)",  "*.drm", "" } ;
  20.  
  21. char szDrumID [] = "DRUM" ;
  22. char szListID [] = "LIST" ;
  23. char szInfoID [] = "INFO" ;
  24. char szSoftID [] = "ISFT" ;
  25. char szDateID [] = "ISCD" ;
  26. char szFmtID  [] = "fmt " ;
  27. char szDataID [] = "data" ;
  28.  
  29. char szSoftware [] = "DRUM by Charles Petzold, "
  30.                      "PC Magazine, Vol. 11, Nos. 9-12" ;
  31.  
  32. char szErrorNoCreate    [] = "File %s could not be opened for writing." ;
  33. char szErrorCannotWrite [] = "File %s could not be written to. Disk full." ;
  34. char szErrorNotFound    [] = "File %s not found or cannot be opened." ;
  35. char szErrorNotDrum     [] = "File %s is not a standard DRUM file." ;
  36. char szErrorUnsupported [] = "File %s is not a supported DRUM file." ;
  37. char szErrorCannotRead  [] = "File %s cannot be read." ;
  38.  
  39. BOOL DrumFileParse (char * szFileName, char * szTitleName)
  40.      {
  41.      static char szBuffer [_MAX_PATH] ;
  42.  
  43.      if (_fullpath (szBuffer, szFileName, _MAX_PATH))
  44.           {
  45.           strcpy (szFileName, szBuffer) ;
  46.  
  47.           if (!GetFileTitle (szFileName, szTitleName, _MAX_FNAME + _MAX_EXT))
  48.                return TRUE ;
  49.           }
  50.  
  51.      return FALSE ;
  52.      }
  53.  
  54. BOOL DrumFileOpenDlg (HWND hwnd, char * szFileName, char * szTitleName)
  55.      {
  56.      ofn.hwndOwner         = hwnd ;
  57.      ofn.lpstrFilter       = szFilter [0] ;
  58.      ofn.lpstrFile         = szFileName ;
  59.      ofn.nMaxFile          = _MAX_PATH ;
  60.      ofn.lpstrFileTitle    = szTitleName ;
  61.      ofn.nMaxFileTitle     = _MAX_FNAME + _MAX_EXT ;
  62.      ofn.Flags             = OFN_CREATEPROMPT ;
  63.      ofn.lpstrDefExt       = "drm" ;
  64.  
  65.      return GetOpenFileName (&ofn) ;
  66.      }
  67.  
  68. BOOL DrumFileSaveDlg (HWND hwnd, char * szFileName, char * szTitleName)
  69.      {
  70.      ofn.hwndOwner         = hwnd ;
  71.      ofn.lpstrFilter       = szFilter [0] ;
  72.      ofn.lpstrFile         = szFileName ;
  73.      ofn.nMaxFile          = _MAX_PATH ;
  74.      ofn.lpstrFileTitle    = szTitleName ;
  75.      ofn.nMaxFileTitle     = _MAX_FNAME + _MAX_EXT ;
  76.      ofn.Flags             = OFN_OVERWRITEPROMPT ;
  77.      ofn.lpstrDefExt       = "drm" ;
  78.  
  79.      return GetSaveFileName (&ofn) ;
  80.      }
  81.  
  82. char * DrumFileWrite (DRUM * pdrum, char * szFileName)
  83.      {
  84.      char        szDateBuf [16] ;
  85.      HMMIO       hmmio ;
  86.      long        lFormat = 1L ;
  87.      MMCKINFO    mmckinfo [3] ;
  88.      struct tm * tmTime ;
  89.      time_t      lTime ;
  90.      WORD        wError = 0 ;
  91.  
  92.      memset (mmckinfo, 0, 3 * sizeof (MMCKINFO)) ;
  93.  
  94.                // Recreate the file for writing
  95.  
  96.      if ((hmmio = mmioOpen (szFileName, NULL,
  97.                             MMIO_CREATE | MMIO_WRITE | MMIO_ALLOCBUF)) == NULL)
  98.           return szErrorNoCreate ;
  99.  
  100.                // Create a "RIFF" chunk with a "CPDR" type
  101.  
  102.      mmckinfo[0].fccType = mmioStringToFOURCC (szDrumID, 0) ;
  103.  
  104.      wError |= mmioCreateChunk (hmmio, &mmckinfo[0], MMIO_CREATERIFF) ;
  105.  
  106.                // Create "LIST" sub-chunk with an "INFO" type
  107.  
  108.      mmckinfo[1].fccType = mmioStringToFOURCC (szInfoID, 0) ;
  109.  
  110.      wError |= mmioCreateChunk (hmmio, &mmckinfo[1], MMIO_CREATELIST) ;
  111.  
  112.                // Create "ISFT" sub-sub-chunk
  113.  
  114.      mmckinfo[2].ckid = mmioStringToFOURCC (szSoftID, 0) ;
  115.  
  116.      wError |= mmioCreateChunk (hmmio, &mmckinfo[2], 0) ;
  117.      wError |= (mmioWrite (hmmio, szSoftware, sizeof (szSoftware)) !=
  118.                                               sizeof (szSoftware)) ;
  119.      wError |= mmioAscend (hmmio, &mmckinfo[2], 0) ;
  120.  
  121.                // Create a time string
  122.  
  123.      time (&lTime) ;
  124.      tmTime = localtime (&lTime) ;
  125.  
  126.      wsprintf (szDateBuf, "%04d-%02d-%02d",
  127.                tmTime->tm_year + 1900, tmTime->tm_mon + 1, tmTime->tm_mday) ;
  128.  
  129.                // Create "ISCD" sub-sub-chunk
  130.  
  131.      mmckinfo[2].ckid = mmioStringToFOURCC (szDateID, 0) ;
  132.  
  133.      wError |= mmioCreateChunk (hmmio, &mmckinfo[2], 0) ;
  134.      wError |= (mmioWrite (hmmio, szDateBuf, strlen (szDateBuf) + 1) !=
  135.                                       (long) strlen (szDateBuf) + 1) ;
  136.      wError |= mmioAscend (hmmio, &mmckinfo[2], 0) ;
  137.      wError |= mmioAscend (hmmio, &mmckinfo[1], 0) ;
  138.  
  139.                // Create "fmt " sub-chunk
  140.  
  141.      mmckinfo[1].ckid = mmioStringToFOURCC (szFmtID, 0) ;
  142.  
  143.      wError |= mmioCreateChunk (hmmio, &mmckinfo[1], 0) ;
  144.      wError |= (mmioWrite (hmmio, (LPSTR) &lFormat, sizeof (long)) !=
  145.                                                     sizeof (long)) ;
  146.      wError |= mmioAscend (hmmio, &mmckinfo[1], 0) ;
  147.  
  148.                // Create the "data" sub-chunk
  149.  
  150.      mmckinfo[1].ckid = mmioStringToFOURCC (szDataID, 0) ;
  151.  
  152.      wError |= mmioCreateChunk (hmmio, &mmckinfo[1], 0) ;
  153.      wError |= (mmioWrite (hmmio, (LPSTR) pdrum, sizeof (DRUM)) !=
  154.                                                  sizeof (DRUM)) ;
  155.      wError |= mmioAscend (hmmio, &mmckinfo[1], 0) ;
  156.      wError |= mmioAscend (hmmio, &mmckinfo[0], 0) ;
  157.  
  158.                // Clean up and return
  159.  
  160.      wError |= mmioClose (hmmio, 0) ;
  161.  
  162.      if (wError)
  163.           {
  164.           mmioOpen (szFileName, NULL, MMIO_DELETE) ;
  165.           return szErrorCannotWrite ;
  166.           }
  167.  
  168.      return NULL ;
  169.      }
  170.  
  171. char * DrumFileRead (DRUM * pdrum, char * szFileName)
  172.      {
  173.      DRUM     drum ;
  174.      HMMIO    hmmio ;
  175.      long     lFormat ;
  176.      MMCKINFO mmckinfo [3] ;
  177.  
  178.      memset (mmckinfo, 0, 2 * sizeof (MMCKINFO)) ;
  179.  
  180.                // Open the file
  181.  
  182.      if ((hmmio = mmioOpen (szFileName, NULL, MMIO_READ)) == NULL)
  183.           return szErrorNotFound ;
  184.  
  185.                // Locate a "RIFF" chunk with a "DRUM" form-type
  186.  
  187.      mmckinfo[0].ckid = mmioStringToFOURCC (szDrumID, 0) ;
  188.  
  189.      if (mmioDescend (hmmio, &mmckinfo[0], NULL, MMIO_FINDRIFF))
  190.           {
  191.           mmioClose (hmmio, 0) ;
  192.           return szErrorNotDrum ;
  193.           }
  194.  
  195.                // Locate, read, and verify the "fmt " sub-chunk
  196.  
  197.      mmckinfo[1].ckid = mmioStringToFOURCC (szFmtID, 0) ;
  198.  
  199.      if (mmioDescend (hmmio, &mmckinfo[1], &mmckinfo[0], MMIO_FINDCHUNK))
  200.           {
  201.           mmioClose (hmmio, 0) ;
  202.           return szErrorNotDrum ;
  203.           }
  204.  
  205.      if (mmckinfo[1].cksize != sizeof (long))
  206.           {
  207.           mmioClose (hmmio, 0) ;
  208.           return szErrorUnsupported ;
  209.           }
  210.  
  211.      if (mmioRead (hmmio, (LPSTR) &lFormat, sizeof (long)) != sizeof (long))
  212.           {
  213.           mmioClose (hmmio, 0) ;
  214.           return szErrorCannotRead ;
  215.           }
  216.  
  217.      if (lFormat != 1)
  218.           {
  219.           mmioClose (hmmio, 0) ;
  220.           return szErrorUnsupported ;
  221.           }
  222.  
  223.                // Go to end of "fmt " sub-chunk
  224.  
  225.      mmioAscend (hmmio, &mmckinfo[1], 0) ;
  226.  
  227.                // Locate, read, and verify the "data" sub-chunk
  228.  
  229.      mmckinfo[1].ckid = mmioStringToFOURCC (szDataID, 0) ;
  230.  
  231.      if (mmioDescend (hmmio, &mmckinfo[1], &mmckinfo[0], MMIO_FINDCHUNK))
  232.           {
  233.           mmioClose (hmmio, 0) ;
  234.           return szErrorNotDrum ;
  235.           }
  236.  
  237.      if (mmckinfo[1].cksize != sizeof (DRUM))
  238.           {
  239.           mmioClose (hmmio, 0) ;
  240.           return szErrorUnsupported ;
  241.           }
  242.  
  243.      if (mmioRead (hmmio, (LPSTR) &drum, sizeof (DRUM)) != sizeof (DRUM))
  244.           {
  245.           mmioClose (hmmio, 0) ;
  246.           return szErrorCannotRead ;
  247.           }
  248.  
  249.                // Close the file and copy the DRUM structure data
  250.  
  251.      mmioClose (hmmio, 0) ;
  252.  
  253.      memcpy (pdrum, &drum, sizeof (DRUM)) ;
  254.      return NULL ;
  255.      }
  256.